package api

import (
	"crypto/sha1"
	"encoding/hex"
	"fmt"
	"hft/global"
	cus_utils "hft/tools/utils"
	"hft/tools/weixin"
	"net/url"
	"sort"
	"strings"
	"time"

	"github.com/tidwall/gjson"
)

// 前面的返回
type SignatureConfig struct {
	NoneStr   string `json:"nonceStr"`
	Timestamp int64  `json:"timestamp"`
	Signature string `json:"signature"`
}

// 缓存jsapi_ticket
const (
	GLOBAL_JS_API_TICKET = "GLOBAL_JS_API_TICKET"
)

type WeiXinJsApi struct{}

func (*WeiXinJsApi) JsApiTicketCache() {
	data := weixin.WeiXinBase.BaseRequestV2("GET", "/cgi-bin/ticket/getticket", &url.Values{"type": []string{"jsapi"}}, []byte{})
	var res = string(data)
	errmsg := gjson.Get(res, "errmsg").String()
	if errmsg != "ok" {
		fmt.Println("获取jsapi_ticket失败1")
	} else {
		ticket := gjson.Get(res, "ticket").String()
		_, err := global.OC_REDIS.Set(GLOBAL_JS_API_TICKET, ticket, 6200*time.Second).Result()
		if err != nil {
			fmt.Println("设置jsapi_ticket失败2")
		}
	}
}

func (w *WeiXinJsApi) GetTicket() string {
	res, err := global.OC_REDIS.Get(GLOBAL_JS_API_TICKET).Result()
	if err != nil {
		w.JsApiTicketCache()
		res, _ := global.OC_REDIS.Get(GLOBAL_JS_API_TICKET).Result()
		return res
	}
	return res
}

// 获取获取前面
func (w *WeiXinJsApi) GetSignature(url string) *SignatureConfig {
	fmt.Println(url)
	newUrl, _ := generateSHA1Hash(url)
	noneStr := cus_utils.SmallBlock.GenerateRandomString(16)
	ticket := w.GetTicket()
	timestamp := time.Now().Unix()
	str := fmt.Sprintf("jsapi_ticket=%s&noncestr=%s&timestamp=%d&url=%s", ticket, noneStr, timestamp, newUrl)
	hasher := sha1.New()
	// 将字符串输入写入哈希
	hasher.Write([]byte(str))
	// 获取哈希的字节表示
	hashBytes := hasher.Sum(nil)
	// 将字节转换为十六进制字符串
	hashString := hex.EncodeToString(hashBytes)
	fmt.Println("jsapi_ticket:", ticket)
	fmt.Println("nonceStr:", noneStr)
	fmt.Println("timestamp:", timestamp)
	fmt.Println("url:", newUrl)
	fmt.Println("signature:", hashString)
	fmt.Println("str:", str)
	return &SignatureConfig{
		Signature: hashString,
		Timestamp: timestamp,
		NoneStr:   noneStr,
	}
}

var WeiXinJsApiBlock = new(WeiXinJsApi)

// 工具
func generateSHA1Hash(inputURL string) (string, error) {
	// 解析URL获取参数
	parsedURL, err := url.Parse(inputURL)
	if err != nil {
		return "", fmt.Errorf("Error parsing URL: %v", err)
	}

	// 获取参数map
	params, err := url.ParseQuery(parsedURL.RawQuery)
	if len(params) == 0 {
		return inputURL, nil
	}
	if err != nil {
		return "", fmt.Errorf("Error parsing query parameters: %v", err)
	}
	// 将参数名和参数值都转换为小写字符
	lowercaseParams := make(map[string]string)
	for key, values := range params {
		// 选择第一个值作为参数值
		lowercaseParams[strings.ToLower(key)] = values[0]
	}
	// 按照键名的字典顺序拼接参数字符串
	var keys []string
	for k := range lowercaseParams {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	// 拼接参数字符串
	var paramString string
	for _, key := range keys {
		paramString += key + "=" + lowercaseParams[key] + "&"
	}

	// 去掉末尾的"&"
	paramString = strings.TrimSuffix(paramString, "&")

	// 对参数字符串进行SHA-1加密
	sha1Hash := sha1.New()
	sha1Hash.Write([]byte(paramString))
	sha1Bytes := sha1Hash.Sum(nil)

	// 将加密结果转换为十六进制字符串
	sha1String := hex.EncodeToString(sha1Bytes)
	newUrl := strings.Split(inputURL, "?")[0] + "?params=" + sha1String
	return newUrl, nil
}
